#ifndef _DAG_SINGLETON_H_
#define _DAG_SINGLETON_H_

namespace dag {
	template <class _doomed>
	class DAG_LOCAL Destroyer {
	public:
		Destroyer(_doomed* doomed)
		:	m_Doomed(doomed)
		{}
		
		virtual ~Destroyer() {
			try {
				delete m_Doomed;
				m_Doomed = NULL;
			}
			catch(...) {
			}
		}
		
		void setDoomed(_doomed* doomed) {
			m_Doomed = doomed;
		}
		
	private:
		Destroyer(const Destroyer<_doomed>&);
		void operator=(const Destroyer<_doomed>&);
		_doomed* m_Doomed;
	};
	
	template<class _derived>
	class DAG_API Singleton : public _derived{
		friend class Destroyer< Singleton<_derived> >;
	public:
		static _derived& instance() {
			if (m_Instance == NULL) {
				m_Instance = new Singleton<_derived>();
			}
			return *m_Instance;
		}
		
	protected:
		Singleton() {
			m_Destroyer.setDoomed(this);
		}
		
		virtual ~Singleton() {}
	private:
		Singleton(const Singleton&);
		Singleton& operator=(const Singleton&);
		
		static Destroyer< Singleton<_derived> > m_Destroyer;
		static Singleton<_derived>* m_Instance;
	};
	
	template<class _derived>
	Destroyer< Singleton<_derived> > Singleton<_derived>::m_Destroyer(NULL);
	
	template<class _derived>
	Singleton<_derived>* Singleton<_derived>::m_Instance = NULL;
}
#endif